package com.thinkit.bigdata.web.service.impl.sec;

import com.thinkit.bigdata.core.feature.orm.mybatis.Page;
import com.thinkit.bigdata.core.util.StringUtil;
import com.thinkit.bigdata.web.dao.config.SysStatusAttMapper;
import com.thinkit.bigdata.web.dao.sec.SysGroupMapper;
import com.thinkit.bigdata.web.dao.sec.SysRoleMapper;
import com.thinkit.bigdata.web.dao.sec.SysUserMapper;
import com.thinkit.bigdata.web.model.config.SysArea;
import com.thinkit.bigdata.web.model.config.SysStatusAtt;
import com.thinkit.bigdata.web.model.config.SysStatusAttExample;
import com.thinkit.bigdata.web.model.result.Constants;
import com.thinkit.bigdata.web.model.sec.*;
import com.thinkit.bigdata.web.service.sec.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户Service实现类
 * Modify by lihongli 2018/9/13
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private SysUserMapper mapper;

    @Resource
    private SysGroupMapper groupMapper;

    @Resource
    private SysStatusAttMapper statusAttMapper;

    @Resource
    private SysRoleMapper roleMapper;

    @Override
    public List<User> selectByExampleAndPage(Page<User> page, UserExample example) {
        // 手动分页
        List<User> result = new ArrayList<>();
        List<User> userList = mapper.selectByExample(example);
        int pageNo = page.getPageNo();
        int pageSize = page.getPageSize();
        // 查询出来的总数量
        int total = userList.size();
        if (total == 0) {
            // 没有数据 返回空数据
            page.setTotalPages(total);
            page.setTotalCount(total);
            page.setResult(result);
        } else {
            // 计算总页数
            int totalPages = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
            page.setTotalPages(totalPages);
            page.setTotalCount(total);
            if (pageNo > totalPages) {
                // 如果要查询的页数 大于总页数 返回第一页数据
                pageNo = 1;
            }
            // 获取要查询的数据（1-10 对应下标0-9）
            for (int i = (pageNo - 1) * pageSize + 1; i <= pageNo * pageSize && i <= total; i++) {
                result.add(userList.get(i - 1));
            }
            // 查询用户状态对应的名称
            SysStatusAttExample statusAttExample = new SysStatusAttExample();
            statusAttExample.createCriteria().andTypeEqualTo("sys_user_status");
            List<SysStatusAtt> sysStatusAttList = statusAttMapper.selectByExample(statusAttExample);
            // 对用户信息中的状态进行修改
            for (User user : userList) {
                for (SysStatusAtt statusAtt : sysStatusAttList) {
                    if (user.getIsdelete() == Integer.valueOf(statusAtt.getValue())) {
                        user.setStatusname(statusAtt.getName());
                    }
                }
            }
            page.setResult(result);
        }
        return result;
    }

    /**
     * 获取当前用户所能看到的所有下级组织机构
     *
     * @return
     */
    public List<Long> getAllSubGroupId(String areaId) {
        List<Long> groupIdList = new ArrayList<>();
        Session session = SecurityUtils.getSubject().getSession();
        // 当前登录用户
        User user = (User) session.getAttribute(Constants.SESSION_USER_INFO);
        Long groupId = user.getGroupid();
        // 获取用户所属省份 判断是不是超管/集团 或者是省份人员
        SysArea area = (SysArea) session.getAttribute("areaInfo");
        // area == null 则为admin、集团人员 (或者集团超管--取消此角色概念)
        if (area == null) {
            if (StringUtil.isNotEmpty(areaId)) {
                // 判断省份id是否为空 不为空的时候 还需要区分是集团人员二级人员在操作
                try {
                    if (groupId != null && user.getGroup().getParentid() != null && Long.valueOf(areaId).longValue() == Constants.GROUP_AREAID.longValue()) {
                        //是集团二级机构的人员 且在查询集团人员信息 则只返回二级机构下人员
                        selectGroupIdByAreaId(Long.valueOf(areaId), groupIdList, true);
                    } else {
                        selectGroupIdByAreaId(Long.valueOf(areaId), groupIdList, false);
                    }
                } catch (NumberFormatException e) {
                    // areaId不合法的时候 啥都不让查询出来
                    groupIdList.add(-404L);
                }
            } else {
                // 如果省份id为空 判断用户角色
                if (groupId != null && user.getGroup().getParentid() != null) {
                    //不是集团最顶层机构的人员 则查询所有省份的人员，以及自己同级的机构下的集团人员
                    selectGroupIdByAreaId(null, groupIdList, false);
                }
                // groupId为空 或者groupId不为空且user.getGroup().getParentid() == null 说明是admin或者集团超管 查询所有人员 groupIdList为空
            }
            return groupIdList;
        }
        // 判断是不是质检或者坐席
        Integer type = user.getGroup().getType();
        if (type == 0 || type == 1) {
            List<SysRole> rolelist = user.getRolelist();
            //是否为组长角色
            boolean isTL = false;
            for (SysRole role : rolelist) {
                if (role.getParentroleid() == null) {
                    isTL = true;
                }
            }
            // 坐席组长或质检组长 可以管理自己所在组
            if (isTL) groupIdList.add(groupId);
                // 否则 存入一个不存在的groupId 保证不能查出数据
            else groupIdList.add(-404L);
        } else {
            // 部门 根据省份id获取 省份下所有组织机构 从而实现可以看到该省份所有用户
            selectGroupIdByAreaId(area.getId().longValue(), groupIdList, false);
        }
        return groupIdList;
    }

    // 根据areaId获取某省份下所有机构id 如果没有 则赋值一个-404的机构id
    // flag用来标记是不是集团二级机构人员在查询集团的人员
    private void selectGroupIdByAreaId(Long areaId, List<Long> groupIdList, boolean flag) {
        // 部门 根据省份id获取 省份下所有组织机构 从而实现可以看到该省份所有用户
        SysGroupExample groupExample = new SysGroupExample();
        if (areaId != null && !flag) {
            groupExample.createCriteria().andAreaidEqualTo(areaId);
        } else if (areaId != null && flag) {
            groupExample.createCriteria().andAreaidEqualTo(areaId).andParentidIsNotNull();
        } else {
            // 传递过来的areaId为null时 获取集团二级机构下集团人员 以及 各省份人员
            groupExample.or().andAreaidEqualTo(Constants.GROUP_AREAID).andParentidIsNotNull();
            groupExample.or().andAreaidNotEqualTo(Constants.GROUP_AREAID);
        }
        List<SysGroup> groupList = groupMapper.selectByExample(groupExample);
        for (SysGroup group : groupList) {
            groupIdList.add(group.getId());
        }
        if (groupIdList.isEmpty()) {
            // 如果省份下没有机构 存储一个不存在的机构id保证查询不出来数据
            groupIdList.add(-404L);
        }
    }

    @Override
    public int insert(User record) {
        //添加用户信息
        int rowNum = mapper.insertSelective(record);
        if (record.getRoleidlist().isEmpty() && record.getSeatgroupidlist().isEmpty()) {
            return rowNum;
        }
        // 如果角色设置信息不为空 写入用户与角色之间的关联关系
        if (!record.getRoleidlist().isEmpty()) {
            rowNum += mapper.insertUserRoleRefInfo(record);
        }
        // 如果坐席组设置信息 写入质检用户与坐席组质检的关联关系
        if (!record.getSeatgroupidlist().isEmpty()) {
            QcRelationDto relation = new QcRelationDto();
            relation.setUserId(record.getId());
            relation.setSeatGroupIdList(record.getSeatgroupidlist());
            rowNum += mapper.insertQcRelation(relation);
        }
        return rowNum;
    }

    @Override
    public int update(User record) {
        // 更新用户信息
        int rowNum = mapper.updateByPrimaryKeySelective(record);
        // 删除用户角色关联信息
        mapper.deleteUserRoleRefInfo(record.getId());
        // 删除用户坐席组关联信息
        QcRelationDto qcRelation = new QcRelationDto();
        qcRelation.setUserId(record.getId());
        mapper.deleteQcRelation(qcRelation);
        if (!record.getRoleidlist().isEmpty()) {
            // 更新角色信息
            mapper.insertUserRoleRefInfo(record);
        }
        if (!record.getSeatgroupidlist().isEmpty()) {
            // 更新人对组信息
            qcRelation.setSeatGroupIdList(record.getSeatgroupidlist());
            mapper.insertQcRelation(qcRelation);
        }
        return rowNum;
    }

//    @Override
//    public int delete(Long id) {
//        return mapper.deleteByPrimaryKey(id);
//    }

//    @Override
//    public int delete(User record) {
//        return mapper.deleteByPrimaryKey(record.getId());
//    }

//    @Override
//    public int deleteByExample(UserExample example) {
//        return mapper.deleteByExample(example);
//    }

    @Override
    public List<User> selectByExample(UserExample example) {
        return mapper.selectByExample(example);
    }

    @Override
    public int updateByExampleSelective(User record, UserExample example) {
        return mapper.updateByExampleSelective(record, example);
    }

    @Override
    public int updateByExampleForCron(User record, UserExample example) {
        return mapper.updateByExampleForCron(record, example);
    }

    //    @Override
//    public int updateByExample(User record, UserExample example) {
//        return mapper.updateByExample(record, example);
//    }

    @Override
    public int updateByPrimaryKeySelective(User record) {
        return mapper.updateByPrimaryKeySelective(record);
    }

//    @Override
//    public int updateByPrimaryKey(User record) {
//        return mapper.updateByPrimaryKey(record);
//    }

    @Override
    public User authentication(User record) {
        return mapper.authentication(record);
    }

    @Override
    public User selectByUsername(String username) {
        UserExample example = new UserExample();
        example.createCriteria().andUsernameEqualTo(username);
        final List<User> list = mapper.selectByExample(example);
        return list.get(0);
    }

    @Override
    public User selectBySeatId(String seatId) {
        UserExample example = new UserExample();
        example.createCriteria().andAccountEqualTo(seatId);
        final List<User> list = mapper.selectByExample(example);
        return list.get(0);
    }

    @Override
    public User getUserByPK(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public Integer deleteUser(List<Long> idList) {
        // 删除用户信息
        UserExample example = new UserExample();
        example.createCriteria().andIdIn(idList);
        int rowNum = mapper.deleteByExample(example);
        // 删除user与role的关联信息
        mapper.batchDeleteUserRoleRefInfo(idList);
        // 删除user与坐席之间的关联信息
        for (Long userId : idList) {
            QcRelationDto qcRelation = new QcRelationDto();
            qcRelation.setUserId(userId);
            mapper.deleteQcRelation(qcRelation);
        }
        return rowNum;
    }

    @Override
    public QcRelationDto selectedSeat(Long userId) {
        return mapper.selectedSeat(userId);
    }

    @Override
    public Integer insertQcRelation(QcRelationDto qcRelation) {
        int rowNum = mapper.deleteQcRelation(qcRelation);
        if (qcRelation.getSeatGroupIdList().isEmpty()) {
            return rowNum;
        }
        return mapper.insertQcRelation(qcRelation);
    }

    @Override
    public int countByExample(UserExample example) {
        return mapper.countByExample(example);
    }

    @Override
    public Integer insertUsers(List<User> userList) {
        int rowNum = 0;
        for (User user : userList) {
            // 校验用户名/email/idcard已存在 则跳过该用户
            UserExample example = new UserExample();
            example.or().andUsernameEqualTo(user.getUsername());
            example.or().andEmailEqualTo(user.getEmail());
            example.or().andIdcardEqualTo(user.getIdcard());
            if (mapper.countByExample(example) > 0) continue;
            // 写入用户信息
            rowNum += mapper.insertSelective(user);
            // 写入用户角色关联信息
            mapper.insertUserRoleRefInfo(user);
        }
        return rowNum;
    }

    @Override
    public List<User> selectUserByAreaId(Long areaId) {
        return mapper.selectUserByAreaId(areaId);
    }

    @Override
    public List<Map<String, Object>> selectAccountByAreaGroupId(Long areaId, Long seatGroupId) {
        return mapper.selectAccountByAreaGroupId(areaId, seatGroupId);
    }

    /**
     * 查询省份下所有坐席，不包括坐席组长
     *
     * @param code
     * @return
     */
    @Override
    public List<User> selectSeatIdByAread(String code) {
        return mapper.selectSeatIdByAread(code);
    }

    @Override
    public List<User> selectSeatIdByGroupId(Long groupId) {
        UserExample example = new UserExample();
        example.createCriteria().andGroupidEqualTo(groupId);
        return mapper.selectByExample(example);
    }

    @Override
    public List<User> selectSeatIdByQc(Long userId, Long groupId) {
        return mapper.selectSeatIdByQc(userId, groupId);
    }

    @Override
    public List<SysGroup> selectManagedSeatGroupByUserId(Long userId) {
        return mapper.selectManagedSeatGroupByUserId(userId);
    }

    @Override
    public List<Map<String, Object>> selectAllSeat() {
        return mapper.selectAllSeat();
    }

    @Override
    public List<Map<String, Object>> selectCreateUser(Map<String, Object> params) {
        return mapper.selectCreateUser(params);
    }

    @Override
    public Integer updateInitPasswordByPrimaryKey(User user) {
        return mapper.updateInitPasswordByPrimaryKey(user);
    }

    @Override
    public List<Map<String, Object>> selectUserDataToExport(UserExample example) {
        List<Map<String, Object>> result = new ArrayList<>();
        List<User> userList = mapper.selectByExample(example);
        // 查询组织机构类型名称
        SysStatusAttExample statusAttExample = new SysStatusAttExample();
        statusAttExample.createCriteria().andTypeEqualTo("sys_group_type");
        List<SysStatusAtt> statusAttList = statusAttMapper.selectByExample(statusAttExample);
        // 对查询到的数据进行处理
        for (User user : userList) {
            Map<String, Object> tmp = new HashMap<>();
            tmp.put("username", user.getUsername());
            SysGroup group = user.getGroup();
            // 区分是不是集团人员
            if ((group == null) || (group != null && group.getAreaid().longValue() == Constants.GROUP_AREAID.longValue())) {
                tmp.put("area", "集团");
            } else {
                tmp.put("area", group.getAreaname());
            }
            if (group != null) {
                // 设置组织机构相关信息
                tmp.put("groupname", getGroupName(group.getId()));
                // 根据组织机构类型查询对应的类型名称
                String groupType = "";
                for (SysStatusAtt statusAtt : statusAttList) {
                    if (statusAtt.getValue().equals(group.getType().toString())) {
                        groupType = statusAtt.getName();
                    }
                }
                tmp.put("grouptype", groupType);
                if (!user.getRolelist().isEmpty()) {
                    tmp.put("rolename", user.getRolelist().get(0).getName());
                }
            } else {
                tmp.put("rolename", "超级管理员");
            }
            // 设置真实名称 账号
            tmp.put("realname", user.getRealname());
            tmp.put("account", user.getAccount());
            tmp.put("mobileno", user.getMobileno());
            tmp.put("idcard", user.getIdcard());
            tmp.put("email", user.getEmail());
            tmp.put("workip", user.getWorkip());
            result.add(tmp);
        }
        return result;
    }

    // 根据C组织机构的id  获取A-B-C的机构名称结构
    private String getGroupName(Long groupId) {
        // 存储结果
        StringBuilder sb = new StringBuilder();
        // 查询C对应的机构名称
        SysGroupExample example = new SysGroupExample();
        example.createCriteria().andIdEqualTo(groupId);
        List<SysGroup> groupList = groupMapper.selectByExample(example);
        if (groupList.isEmpty()) {
            return "";
        }
        SysGroup group = groupList.get(0);
        sb.insert(0, group.getName() + "-");
        // 根据parentId循环获取上级机构的名称
        Long parentid = group.getParentid();
        while (parentid != null) {
            SysGroupExample sysGroupExample = new SysGroupExample();
            sysGroupExample.createCriteria().andIdEqualTo(parentid);
            List<SysGroup> sysGroupList = groupMapper.selectByExample(sysGroupExample);
            if (sysGroupList.isEmpty()) {
                break;
            }
            sb.insert(0, sysGroupList.get(0).getName() + "-");
            parentid = sysGroupList.get(0).getParentid();
        }
        String result = sb.toString();
        if (result.length() > 0) {
            return sb.toString().substring(0, sb.toString().length() - 1);
        }
        return "";
    }

    // 根据角色id查询用户id
    public List<Long> selectUserIdByRoleId(List<Long> roleIdList) {
        return mapper.selectUserIdByRoleId(roleIdList);
    }

    /**
     * 根据userId获取其组员userId（含自己）
     * 组长组员必须属于同一组织机构
     *
     * @param userId 用户id
     * @return List<Long> 用户ids
     */
    public List<Long> selectMemberIdByLeaderId(Long userId) {
        List<Long> userIdList = new ArrayList<>();

        if (userId != null) {
            // 根据userId获取组织机构信息
            User user = mapper.selectByPrimaryKey(userId);

            if (user != null) {
                userIdList.add(userId);
            }

            // 根据userId获取角色信息
            List<SysRole> sysRoles = roleMapper.selectRoleByUserId(userId);
            List<Long> roleIds = new ArrayList<>();
            for (SysRole sysRole : sysRoles) {
                roleIds.add(sysRole.getId());
            }

            if (!roleIds.isEmpty()) {
                // 根据角色id查询其子角色id
                SysRoleExample sysRoleExample = new SysRoleExample();
                SysRoleExample.Criteria sysRoleCriteria = sysRoleExample.createCriteria();
                sysRoleCriteria.andParentroleidIn(roleIds);
                List<SysRole> sysRoleList = roleMapper.selectByExample(sysRoleExample);
                List<Long> roleIdList = new ArrayList<>();
                for (SysRole sysRole : sysRoleList) {
                    roleIdList.add(sysRole.getId());
                }

                if (!roleIdList.isEmpty()) {
                    // 根据角色id查询用户id
                    List<Long> userIds = mapper.selectUserIdByRoleId(roleIdList);

                    // 根据userIds及groupId查询用户信息
                    UserExample userExample = new UserExample();
                    UserExample.Criteria userCriteria = userExample.createCriteria();
                    userCriteria.andGroupidEqualTo(user.getGroupid());
                    if (!userIds.isEmpty()) {
                        userCriteria.andIdIn(userIds);
                    }
                    List<User> users = mapper.selectByExample(userExample);
                    for (User u : users) {
                        userIdList.add(u.getId());
                    }
                }
            }
        }

        return userIdList;
    }


    /**
     * @param userId 用户id
     * @return
     */
    public List<User> selectUserListById(List userId) {
        List<User> userList = mapper.selectUserListById(userId);
        return userList;
    }
}
